#include <chrono>
#include <iterator>
#include <log.h>
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/bind/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include "boost/system/detail/error_code.hpp"
#include "rtmp.h"

#include <thread>

using namespace std;
using boost::asio::ip::tcp;
using boost::asio::ip::udp;



class tcp_connection
: public boost::enable_shared_from_this<tcp_connection>
{
	public:
		typedef boost::shared_ptr<tcp_connection> pointer;

		static pointer create(boost::asio::io_context& io_context)
		{
			return pointer(new tcp_connection(io_context));
		}

		tcp::socket& socket()
		{
			return socket_;
		}

		void start()
		{

			auto self(shared_from_this());
			socket_.async_wait(tcp::socket::wait_read, [this, self](const boost::system::error_code& error){
					if (error == boost::asio::error::eof || error == boost::asio::error::connection_reset) {
					// The client has disconnected, handle the disconnection event in the session object
						handle_disconnect();
					} else if(!error) {
						cout << "async_read" << endl;
						// async_read_some 会读取一次tcp缓冲区内容，之后直接返回。如果使用
						// async_read 则需要指定一个确定的数量，接收到这个确定数目之前不会调用回调
						socket_.async_read_some(boost::asio::buffer(message_, max_length),
								boost::bind(&tcp_connection::handle_read, shared_from_this(),
									boost::asio::placeholders::error, boost::placeholders::_2));
						
					}
			});
			

		}

	private:
		tcp_connection(boost::asio::io_context& io_context)
			: socket_(io_context), rtmp_(&socket_)
		{
			std::cout << "Create Connection!!" << std::endl;
		}

		void handle_write(const boost::system::error_code& error, std::size_t transfered)
		{
			start();
			if (!error) {
				cout << "Write to Client Done, size:" << transfered << endl;
			}
		}

		void handle_read(const boost::system::error_code& error, std::size_t transfered)
		{
			std::cout << transfered  << std::endl;
			if (!error) {
				// 多协议支持, 将message_通过多层filter，每种处理方法中首先对接收的数据正确性做判断
				rtmp_.rtmp_recv(message_, transfered);

			} else {
				std::cout << error.what() << std::endl;
			}

			//std::this_thread::sleep_for(std::chrono::seconds(1));
			start();
			//boost::asio::async_write(socket_, boost::asio::buffer(message_),
					//boost::bind(&tcp_connection::handle_write, shared_from_this(),
						//boost::asio::placeholders::error, boost::placeholders::_2));

		}

		void handle_disconnect()
		{
			std::cout << "Connection Break" << std::endl;
			socket_.close();
			auto self = shared_from_this();
			std::cout << "self.use_count: " << self.use_count() << std::endl;
		}

		tcp::socket socket_;
		enum {max_length = 2*1024*1024};
		char message_[max_length];
		rtmp rtmp_;
};

class tcp_server
{
	public:
		tcp_server(boost::asio::io_context& io_context)
			: io_context_(io_context),
			acceptor_(io_context, tcp::endpoint(tcp::v4(), 6666))
	{

		start_accept();
	}

		~tcp_server()
		{
		}

	private:
		void start_accept()
		{
			tcp_connection::pointer new_connection =
				tcp_connection::create(io_context_);

			acceptor_.async_accept(new_connection->socket(),
					boost::bind(&tcp_server::handle_accept, this, new_connection,
						boost::asio::placeholders::error));
		}

		void handle_accept(tcp_connection::pointer new_connection,
				const boost::system::error_code& error)
		{
			if (!error)
			{
				new_connection->start();
			}

			ALOGD("loop");
			start_accept();
		}

		boost::asio::io_context& io_context_;
		tcp::acceptor acceptor_;
};

int main(int argc, char* argv[]) {

	try
	{
		boost::asio::io_context io_context;
		tcp_server server1(io_context);
		io_context.run();
	}
	catch (std::exception& e)
	{
		std::cerr << e.what() << std::endl;
	}

	return 0;
}
